#-------------------------------------------------------------------------------
# Name:       ppt_to_png_and_notes_converter.py
# Purpose:    Convert PowerPoint to image files and extract speaker notes
#
# Authors:    Glenn Ramsey <glenn.ramsey@slidespeech.com>
#             John Graves <john.graves@slidespeech.com>
#
# Copyright:  (c) Slidespeech Ltd 2012
# Licence:    MIT license
#-------------------------------------------------------------------------------
import os
import win32com.client
import threading
import pythoncom

from converter import Converter
from converter_error import ConverterError

from notes_to_QAR_converter import NotesToQARConverter


class PPTToPNGAndNotesConverter(Converter):
    def __init__(self, pptPath, pptFile, language, tempDir=None, previous=None):
        Converter.__init__(self, previous)
        if tempDir:
            self._tempDir = tempDir
        self._pptPath = pptPath
        self._pptFile = pptFile
        self._language = language

    def _convertImpl(self):

        # create image files

        self._imageDir = os.path.join(self.tempDir(), "images", "CONTENTS")
        try:
            os.makedirs(self._imageDir)
        except OSError:
            # dir already exists, shouldn't happen
            pass

        notesList = []
        imageFileList = []

        # Because this is running in a worker thread we have to call coinitialize
        if threading.currentThread ().getName () <> 'MainThread':
            pythoncom.CoInitialize ()

        try:
            Application = win32com.client.Dispatch("PowerPoint.Application") #, clsctx = pythoncom.CLSCTX_LOCAL_SERVER)
            #Application = win32com.client.gencache.EnsureDispatch("PowerPoint.Application")
        except Exception as e:
            ex = ConverterError("Powerpoint is not available", e)
            raise ex

        try:
            Application.Visible = True
            # ^ must be True, causes an exception if False

            Presentation = Application.Presentations.Open(os.path.join(self._pptPath,self._pptFile))
            onSlide = 0

            for Slide in Presentation.Slides:
                imageName = "slide-" + str(onSlide) + ".png"
                imageFileList.append(os.path.join(self._imageDir, imageName))
                Slide.Export(imageFileList[onSlide], "PNG", 800, 600) # FIXME: can this fail? need to deal with it
                onSlide += 1
                # print "slide:", onSlide

                for Shape in Slide.NotesPage.Shapes:
                    if Shape.HasTextFrame:
                        if Shape.TextFrame.HasText:
                            text = Shape.TextFrame.TextRange.Text
                            if not text.isdigit():
                                notesList.append(text)

            Application.Quit()
        except Exception as ex:
            e = ConverterError("Could not convert file: %s" % (os.path.join(self._pptPath,self._pptFile)))
            e.cause = ex
            raise e
        finally:
            if threading.currentThread ().getName () <> 'MainThread':
                pythoncom.CoUninitialize()

        # Create and populate the script data structure

        s = {}
        # the top level is a Sequence
        seq = []
        for i in range(len(notesList)):
            q = {}
            q['t'] = "slide-{0}".format(i)
            q['l'] = self._language
            q['q'] = notesList[i]
            # absolute path of image file
            q['i'] = imageFileList[i]
            seq.append(q)
        s['S'] = seq

        self._script = s

    def script(self):
        return self._script

if __name__ == '__main__':
    c = PPTToPNGAndNotesConverter(os.path.join(os.getcwd(),'test'),
                                  "One Slide One Question.pptx",
                                  "en",
                                  tempDir=os.path.join(os.getcwd(),'tmp'))
    c.convert()
    print(c.script())